package com.utilities.visualiser.circularContigs;

import java.io.FileReader;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Element;

import com.utilities.IO.FileUtilities;
import com.utilities.parsers.gff3FileParser.ParseAllContigsFileParser;
import com.utilities.parsers.gff3FileParser.ParseEvents;
import com.utilities.parsers.gff3FileParser.ParseListener;
import com.utilities.visualiser.PrepareXMLFile;

public class Gff3Visualiser extends ParseListener {
	
	String[] colors = {"maroon","red","blue","green","orange", "purple","fuchsia","navy",
			"lime","olive","yellow","teal","aqua","silver","gray","white","black"};
	PrepareXMLFile prepareXMLFile = null;
	Element directScoreFeature = null;
	String radiusAdjustment = null;
	String featureSlotId = null;
	String featureColor = null;
	ParseAllContigsFileParser allContigsFileParser = null;
	
	public static void main(String[] args) throws Exception
	{
		if (args.length == 0)
		{
			args = new String[3];
			args[0] = "4641555"; args[1] = "c:/database/454/7328Run1Others.Gff3" ;
//			args[2] = "c:/database/454/7328Run2Others.gff3"; args[3] = "c:/database/454/Gamma22Run1Others.gff3" ;
//			args[4] = "c:/database/454/Gamma22Run2Others.GFF3"; args[5] = "c:/database/454/Gamma52Run1Others.Gff3" ;
//			args[6] = "c:/database/454/Gamma52Run2Others.GFF3"; args[7] = "c:/database/454/Gamma70Run1Others.GFF3" ;
			args[2] = "c:/database/454/454Annotations.xml";
		}
		
		Gff3Visualiser gff3Visualiser = new Gff3Visualiser();
		gff3Visualiser.prepareXMLFile = new PrepareXMLFile().initialise();
		gff3Visualiser.makeFeatureSlots(gff3Visualiser.initialise(args[0],args), args.length - 1);
		
		gff3Visualiser.allContigsFileParser = 
			new ParseAllContigsFileParser();
		for (int i = 1; i < args.length - 1; i++)
		{
			gff3Visualiser.featureColor = gff3Visualiser.colors[i-1];
			gff3Visualiser.featureSlotId = "directStrand" + i;
			gff3Visualiser.allContigsFileParser.addListener(gff3Visualiser);
			gff3Visualiser.allContigsFileParser.parse(new FileReader(args[i]));
			gff3Visualiser.allContigsFileParser.removeAllListeners();
		}
		gff3Visualiser.prepareXMLFile.writeToFile(args[args.length - 1]);
	}

	private PrepareXMLFile initialise(String seqLength, String[] args) throws ParserConfigurationException 
	{
		PrepareXMLFile result = prepareXMLFile.createCGView(seqLength)
		.createLegend("sideLegend", "upper-right", "SanSerif, plain, 10", "0.8");
		
		for (int i = 1; i < args.length; i++)
		{
			String legendLabel = FileUtilities.removeExtension(FileUtilities.getAbstractPath(args[i]));
			result = result.createLegendItem("sideLegend", legendLabel, "SanSerif, plain, 12", true, this.colors[i - 1]);
		}
		result = result.createLegend("lowerleftlegend", "lower-left", "SanSerif, plain, 9", "0.8")
		.createLegendItem("lowerleftlegend", "This map was generated using CGView", null, false, null)
		.createLegend("lowerrightlegend", "lower-right", "SanSerif, plain, 9", "0.8")
		.createLegendItem("lowerrightlegend", "Work done at D-BSSE ETH Zurich", null, false, null);
		return result;
	}
	
	private PrepareXMLFile makeFeatureSlots(PrepareXMLFile prepareXMLFile, int slots) 
	{
		PrepareXMLFile result = prepareXMLFile;
		for(int i = 1; i <= slots; i++)
		{
			result = result.createFeatureSlots("directStrand" + i, "direct",false);
		}
		return result;
	}
	
	@Override
	public void handleEvent(ParseEvents event) {
		try
		{
			switch((ParseEvents.EventTypes)event.getEventType())
			{
				case docStarted : 
					break;
				case docEnded : break; 
				case contigEncountered : 
				{
					System.out.println((String)event.getSource());
					break;
				}
				case headerRead: break;
				case InvalidatorEncountered : 
				{
					String[] params = allContigsFileParser.parseGFF3FileLine((String)event.getSource());
					int startIndex = Integer.parseInt(params[3]);
					int endIndex = Integer.parseInt(params[4]);
					if(startIndex > endIndex)
					{
						startIndex = Integer.parseInt(params[4]);
						endIndex = Integer.parseInt(params[3]);
					}
					String mouseOver = "Start = " + startIndex + ", stop = " + endIndex;
					Element feature = prepareXMLFile.createFeature(featureSlotId, featureColor, "clockwise-arrow", 
							"errors", null,mouseOver,null,null,radiusAdjustment);
					prepareXMLFile.createFeatureRange(feature, String.valueOf(startIndex), String.valueOf(endIndex), null);
					break;
				}
				case geneEncountered : 
					{
						String[] params = allContigsFileParser.parseGFF3FileLine((String)event.getSource());
						int startIndex = Integer.parseInt(params[3]);
						int endIndex = Integer.parseInt(params[4]);
						if(startIndex > endIndex)
						{
							startIndex = Integer.parseInt(params[4]);
							endIndex = Integer.parseInt(params[3]);
						}
						String geneName = null;
						String[] attributes = params[8].split(";");
						for (String attribute : attributes)
						{
							String[] pair = attribute.split("=");
							if (pair[0].equalsIgnoreCase("NAME"))
							{
								geneName = pair[1];
							}
						}
						
						String mouseOver = "Start = " + startIndex + ", stop = " + endIndex;
						Element feature = prepareXMLFile.createFeature(featureSlotId, featureColor, "clockwise-arrow", 
								geneName, null,mouseOver,null,null,radiusAdjustment);
						prepareXMLFile.createFeatureRange(feature, String.valueOf(startIndex), String.valueOf(endIndex), null);
						break;
					}
				case seqRead: break;
				case seqStarted: break;
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
			System.exit(1);
		}
	}
}
